package com.homedo.microservice.open.service.gateway.manager.web.remote.api.impl;

import com.google.common.collect.Lists;
import com.homedo.common.bean.data.RequestData;
import com.homedo.common.bean.data.ResponseData;
import com.homedo.common.exception.HomedoException;
import com.homedo.common.util.Detect;
import com.homedo.microservice.open.service.gateway.manager.web.api.IServiceGatewayServiceRemote;
import com.homedo.microservice.open.service.gateway.manager.web.api.bean.model.req.*;
import com.homedo.microservice.open.service.gateway.manager.web.api.bean.model.resp.ServiceGatewayAResp;
import com.homedo.microservice.open.service.gateway.manager.web.api.bean.model.resp.ServiceGatewayPageAResp;
import com.homedo.microservice.open.service.gateway.manager.web.bean.constant.EnvConstant;
import com.homedo.microservice.open.service.gateway.manager.web.bean.po.DbSource;
import com.homedo.microservice.open.service.gateway.manager.web.bean.po.ServiceGateway;
import com.homedo.microservice.open.service.gateway.manager.web.bean.po.enhanced.ServiceGatewayEnhanced;
import com.homedo.microservice.open.service.gateway.manager.web.convent.CommonConvent;
import com.homedo.microservice.open.service.gateway.manager.web.service.ServiceGatewayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
public class ServiceGatewayServiceRemoteImpl implements IServiceGatewayServiceRemote {

    @Autowired
    private ServiceGatewayService serviceGatewayService;

    @Override
    public ResponseData<ServiceGatewayPageAResp> list(@RequestBody RequestData<ServcieGatewayPageAReq> requestData) {
        ResponseData<ServiceGatewayPageAResp> responseData = new ResponseData<>();

        List<ServiceGatewayEnhanced> serviceGatewayEnhanceds = serviceGatewayService.getEnhancedsAll(null);

        ServiceGatewayPageAResp serviceGatewayPageAResp = new ServiceGatewayPageAResp();
        if (Detect.notEmpty(serviceGatewayEnhanceds)) {
            serviceGatewayPageAResp.setItems(CommonConvent.convent2ServcieGatewayAResps(serviceGatewayEnhanceds));
        }
        responseData.setData(serviceGatewayPageAResp);

        return responseData;
    }

    @Override
    public ResponseData<ServiceGatewayPageAResp> listDistinct(@RequestParam(required = false) String likeComment) {
        ResponseData<ServiceGatewayPageAResp> responseData = new ResponseData<>();

        List<ServiceGatewayEnhanced> serviceGatewayEnhanceds = serviceGatewayService.getEnhancedsAll(null);

        List<ServiceGatewayEnhanced> serviceGatewayEnhanceds4Distinct = Lists.newArrayList();
        if (Detect.notEmpty(serviceGatewayEnhanceds)) {
            Set<String> names = serviceGatewayEnhanceds.stream().map(ServiceGatewayEnhanced::getName).collect(Collectors.toSet());
            names.forEach(e -> {
                serviceGatewayEnhanceds4Distinct.add(this.getDistinct(e, serviceGatewayEnhanceds));
            });

            if (Detect.notEmpty(likeComment)) {
                try {
                    likeComment = URLDecoder.decode(likeComment, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                Iterator<ServiceGatewayEnhanced> iterator = serviceGatewayEnhanceds4Distinct.iterator();
                while (iterator.hasNext()) {
                    if (!iterator.next().getComment().contains(likeComment)) {
                        iterator.remove();
                    }
                }
            }
        }

        ServiceGatewayPageAResp serviceGatewayPageAResp = new ServiceGatewayPageAResp();
        serviceGatewayPageAResp.setItems(CommonConvent.convent2ServcieGatewayAResps(serviceGatewayEnhanceds4Distinct));

        responseData.setData(serviceGatewayPageAResp);

        return responseData;
    }

    private ServiceGatewayEnhanced getDistinct(String name, List<ServiceGatewayEnhanced> serviceGatewayEnhanceds) {
        for (ServiceGatewayEnhanced serviceGatewayEnhanced : serviceGatewayEnhanceds) {
            if (serviceGatewayEnhanced.getName().equals(name)) {
                return serviceGatewayEnhanced;
            }
        }
        return null;
    }

    @Override
    public ResponseData<ServiceGatewayPageAResp> detail(@PathVariable("gateway") String gateway) {
        ResponseData<ServiceGatewayPageAResp> responseData = new ResponseData<>();

        List<ServiceGatewayEnhanced> serviceGatewayEnhanceds = serviceGatewayService.getEnhancedsByName(gateway, null, null);

        ServiceGatewayPageAResp serviceGatewayPageAResp = new ServiceGatewayPageAResp();
        if (Detect.notEmpty(serviceGatewayEnhanceds)) {
            serviceGatewayPageAResp.setItems(CommonConvent.convent2ServcieGatewayAResps(serviceGatewayEnhanceds));
        }
        responseData.setData(serviceGatewayPageAResp);

        return responseData;
    }

    @Override
    public ResponseData<ServiceGatewayPageAResp> detail(@PathVariable("gateway") String gateway, @PathVariable("env") String env) {
        ResponseData<ServiceGatewayPageAResp> responseData = new ResponseData<>();

        List<ServiceGatewayEnhanced> serviceGatewayEnhanceds = serviceGatewayService.getEnhancedsByName(gateway, Lists.newArrayList(env), null);

        ServiceGatewayPageAResp serviceGatewayPageAResp = new ServiceGatewayPageAResp();
        if (Detect.notEmpty(serviceGatewayEnhanceds)) {
            serviceGatewayPageAResp.setItems(CommonConvent.convent2ServcieGatewayAResps(serviceGatewayEnhanceds));
        }
        responseData.setData(serviceGatewayPageAResp);

        return responseData;
    }

    @Override
    public ResponseData<ServiceGatewayAResp> add(@RequestBody RequestData<ServiceGatewayAddAReq> requestData) {
        ResponseData<ServiceGatewayAResp> responseData = new ResponseData<>();

        ServiceGatewayAddAReq serviceGatewayAddAReq = requestData.getRequest();
        String env = EnvConstant.DEV;
        double sort = 1;

        ServiceGateway serviceGateway = new ServiceGateway();
        serviceGateway.setEnv(env);
        serviceGateway.setName(serviceGatewayAddAReq.getName());
        serviceGateway.setComment(serviceGatewayAddAReq.getComment());
        serviceGateway.setSort(sort);

        serviceGateway = serviceGatewayService.saveServiceGateway(serviceGateway, null, null);

        responseData.setData(CommonConvent.convent2ServcieGatewayAResp((ServiceGatewayEnhanced) serviceGatewayService.convent2Enhanced(serviceGateway)));

        return responseData;
    }

    @Override
    public ResponseData<ServiceGatewayAResp> addDetail(@RequestBody RequestData<ServiceGatewayAddAReq> requestData) {
        ResponseData<ServiceGatewayAResp> responseData = new ResponseData<>();

        ServiceGatewayAddAReq serviceGatewayAddAReq = requestData.getRequest();
        DbSourceAddAReq dbSourceAddAReq = serviceGatewayAddAReq.getDbSource();
        String env = serviceGatewayAddAReq.getEnv();

        double sort = 0;
        switch (env) {
            case EnvConstant.DEV:
                sort = 1;
                break;
            case EnvConstant.FAT:
                sort = 2;
                break;
            case EnvConstant.UAT:
                sort = 3;
                break;
            case EnvConstant.PRO:
                sort = 4;
                break;
            default:
                throw new HomedoException("[未知环境]");
        }

        ServiceGateway serviceGateway = new ServiceGateway();
        serviceGateway.setEnv(env);
        serviceGateway.setName(serviceGatewayAddAReq.getName());
        serviceGateway.setComment(serviceGatewayAddAReq.getComment());
        serviceGateway.setSort(sort);

        DbSource dbSource = new DbSource();
        dbSource.setServiceGatewayName(dbSourceAddAReq.getServiceGatewayName());
        dbSource.setEnv(dbSourceAddAReq.getEnv());
        dbSource.setIp(dbSourceAddAReq.getIp());
        dbSource.setPort(dbSourceAddAReq.getPort());
        dbSource.setDbName(dbSourceAddAReq.getDbName());
        dbSource.setUsername(dbSourceAddAReq.getUsername());
        dbSource.setPassword(dbSourceAddAReq.getPassword());

        serviceGateway = serviceGatewayService.saveServiceGateway(serviceGateway, dbSource, null);

        responseData.setData(CommonConvent.convent2ServcieGatewayAResp((ServiceGatewayEnhanced) serviceGatewayService.convent2Enhanced(serviceGateway)));

        return responseData;
    }

    @Override
    public ResponseData update(@RequestBody RequestData<ServiceGatewayUpdateAReq> requestData) {
        ResponseData responseData = new ResponseData();

        ServiceGatewayUpdateAReq serviceGatewayUpdateAReq = requestData.getRequest();
        serviceGatewayService.updateServiceGateway(serviceGatewayUpdateAReq.getName(), serviceGatewayUpdateAReq.getNewName(), serviceGatewayUpdateAReq.getNewComment(), null);

        return responseData;
    }

    @Override
    public ResponseData updateHystrixUrl(@RequestBody RequestData<ServiceGatewayUpdateAReq> requestData) {
        ResponseData responseData = new ResponseData();
        ServiceGatewayUpdateAReq serviceGatewayUpdateAReq = requestData.getRequest();
        serviceGatewayService.updateHystrixUrl(serviceGatewayUpdateAReq.getName(), serviceGatewayUpdateAReq.getEnv(), serviceGatewayUpdateAReq.getHystrixUrl(), null);

        return responseData;
    }

    @Override
    public ResponseData delete(@RequestBody RequestData<ServiceGatewayDeleteAReq> requestData) {
        ResponseData responseData = new ResponseData();

        ServiceGatewayDeleteAReq serviceGatewayDeleteAReq = requestData.getRequest();

        serviceGatewayService.deleteServiceGateway(serviceGatewayDeleteAReq.getName(), serviceGatewayDeleteAReq.getEnv(), null);

        return responseData;
    }
}
